-- lua/lingma/ui.lua
-- UI 相关：浮动窗口显示建议，插入代码，关闭预览
local M = {}

-- 保存上下文
M._context = {
  current_win = nil, -- 预览窗口
  current_buf = nil, -- 预览 buffer
  current_content = "",
  main_win = nil,    -- 主窗口
  main_buf = nil,    -- 主 buffer
  main_cursor = nil, -- 主光标位置
}

-- 显示预览窗口
function M.show_preview(content)
  if not content or content == "" then
    vim.notify("无内容可预览", vim.log.levels.WARN)
    return
  end

  -- 保存主上下文
  local ctx = M._context
  ctx.main_win = vim.api.nvim_get_current_win()
  ctx.main_buf = vim.api.nvim_win_get_buf(ctx.main_win)
  ctx.main_cursor = vim.api.nvim_win_get_cursor(ctx.main_win)
  ctx.current_content = content

  -- 分割内容为行
  local lines = vim.split(content, "\n", { trimempty = true })
  if #lines == 0 then lines = { "" } end

  -- 创建预览 buffer
  local preview_buf = vim.api.nvim_create_buf(false, true)
  if not preview_buf then
    vim.notify("无法创建预览 buffer", vim.log.levels.ERROR)
    return
  end

  -- 设置 buffer 选项
  vim.api.nvim_buf_set_lines(preview_buf, 0, -1, false, lines)
  vim.api.nvim_buf_set_option(preview_buf, "bufhidden", "wipe")
  vim.api.nvim_buf_set_option(preview_buf, "modifiable", false)

  -- 计算窗口大小
  local width = math.max(vim.fn.strwidth(content), 30)
  local height = #lines

  -- 创建预览窗口
  local preview_win = vim.api.nvim_open_win(preview_buf, false, {
    relative = "cursor",
    width = width,
    height = height,
    row = 1,
    col = 0,
    style = "minimal",
    border = "rounded",
  })

  if not vim.api.nvim_win_is_valid(preview_win) then
    vim.api.nvim_buf_delete(preview_buf, { force = true })
    return
  end

  -- 设置窗口选项
  vim.api.nvim_win_set_option(preview_win, "winblend", 15)

  -- 保存预览窗口和 buffer
  ctx.current_win = preview_win
  ctx.current_buf = preview_buf

  -- 绑定按键
  local keymaps = {
    { "n", "<Enter>", M.accept },
    { "n", "<C-y>", M.accept },
    { "n", "q", M.close_preview },
    { "n", "<Esc>", M.close_preview },
    { "i", "<Esc>", M.close_preview },
  }
  for _, map in ipairs(keymaps) do
    vim.api.nvim_buf_set_keymap(preview_buf, map[1], map[2], "", {
      nowait = true,
      noremap = true,
      silent = true,
      callback = map[3],
    })
  end

  -- 确保预览窗口获得焦点
  vim.api.nvim_set_current_win(preview_win)
  vim.api.nvim_win_set_cursor(preview_win, { 1, 0 })
end

-- 插入到主 buffer
function M.accept()
  local ctx = M._context
  local content = ctx.current_content
  if not content or content == "" then
    M.close_preview()
    return
  end

  -- 检查主上下文
  if not ctx.main_win or not ctx.main_buf or not ctx.main_cursor then
    vim.notify("主上下文丢失，无法插入", vim.log.levels.ERROR)
    M.close_preview()
    return
  end

  if not vim.api.nvim_win_is_valid(ctx.main_win) or not vim.api.nvim_buf_is_valid(ctx.main_buf) then
    vim.notify("主窗口或 buffer 无效", vim.log.levels.ERROR)
    M.close_preview()
    return
  end

  -- 插入内容到主 buffer
  local row = ctx.main_cursor[1]
  local col = ctx.main_cursor[2]
  local lines = vim.split(content, "\n", { trimempty = true })

  -- 清理提示词所在行
  vim.api.nvim_buf_set_lines(ctx.main_buf, row - 1, row, false, { "" })

  -- 插入补全内容
  vim.api.nvim_buf_set_lines(ctx.main_buf, row - 1, row - 1, false, lines)
  vim.api.nvim_win_set_cursor(ctx.main_win, { row - 1 + #lines, col })
  vim.notify("代码已插入", vim.log.levels.INFO)

  M.close_preview()
end

-- 安全关闭预览
function M.close_preview()
  local ctx = M._context
  if ctx.current_win and vim.api.nvim_win_is_valid(ctx.current_win) then
    vim.api.nvim_win_close(ctx.current_win, true)
  end

  -- 清除上下文
  M._context = {
    current_win = nil,
    current_buf = nil,
    current_content = "",
    main_win = nil,
    main_buf = nil,
    main_cursor = nil,
  }
end

return M
